﻿using System;
using System.Collections.Specialized;
using System.IO;
using System.Security.Principal;
using System.Text;
using System.Web;

namespace NWebMock
{
    public class HttpRequestWrapper : IHttpRequest
    {
        #region Constructors

        public HttpRequestWrapper(HttpRequest request)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            this.innerRequest = request;
        }

        #endregion

        #region Fields

        private IHttpBrowserCapabilities innerBrowser = null;
        private IHttpClientCertificate innerClientCertificate = null;
        private IHttpCookieCollection innerCookies = null;
        private IHttpFileCollection innerFiles = null;
        private HttpRequest innerRequest = null;

        #endregion

        #region Properties

        public string[] AcceptTypes { get { return this.innerRequest.AcceptTypes; } }

        public string AnonymousID { get { return this.innerRequest.AnonymousID; } }

        public string ApplicationPath { get { return this.innerRequest.ApplicationPath; } }

        public string AppRelativeCurrentExecutionFilePath { get { return this.innerRequest.AppRelativeCurrentExecutionFilePath; } }

        public IHttpBrowserCapabilities Browser
        {
            get
            {
                if (this.innerBrowser != null)
                {
                    return this.innerBrowser;
                }

                if (this.innerRequest.Browser != null)
                {
                    this.innerBrowser = new HttpBrowserCapabilitiesWrapper(this.innerRequest.Browser);
                }

                return this.innerBrowser;
            }
        }

        public IHttpClientCertificate ClientCertificate
        {
            get
            {
                if (this.innerClientCertificate != null)
                {
                    return this.innerClientCertificate;
                }

                if (this.innerRequest.ClientCertificate != null)
                {
                    this.innerClientCertificate = new HttpClientCertificateWrapper(this.innerRequest.ClientCertificate);
                }

                return this.innerClientCertificate;
            }
        }

        public Encoding ContentEncoding { get { return this.innerRequest.ContentEncoding; } set { this.innerRequest.ContentEncoding = value; } }

        public int ContentLength { get { return this.innerRequest.ContentLength; } }

        public string ContentType { get { return this.innerRequest.ContentType; } set { this.innerRequest.ContentType = value; } }

        public IHttpCookieCollection Cookies
        {
            get
            {
                if (this.innerCookies != null)
                {
                    return this.innerCookies;
                }

                if (this.innerRequest.Cookies != null)
                {
                    this.innerCookies = new HttpCookieCollectionWrapper(this.innerRequest.Cookies);
                }

                return this.innerCookies;
            }
        }

        public string CurrentExecutionFilePath { get { return this.innerRequest.CurrentExecutionFilePath; } }

        public string FilePath { get { return this.innerRequest.FilePath; } }

        public IHttpFileCollection Files
        {
            get
            {
                if (this.innerFiles != null)
                {
                    return this.innerFiles;
                }

                if (this.innerRequest.Files != null)
                {
                    this.innerFiles = new HttpFileCollectionWrapper(this.innerRequest.Files);
                }

                return this.innerFiles;
            }
        }

        public Stream Filter { get { return this.innerRequest.Filter; } set { this.innerRequest.Filter = value; } }

        public NameValueCollection Form { get { return this.innerRequest.Form; } }

        public NameValueCollection Headers { get { return this.innerRequest.Headers; } }

        public string HttpMethod { get { return this.innerRequest.HttpMethod; } }

        public Stream InputStream { get { return this.innerRequest.InputStream; } }

        public bool IsAuthenticated { get { return this.innerRequest.IsAuthenticated; } }

        public bool IsLocal { get { return this.innerRequest.IsLocal; } }

        public bool IsSecureConnection { get { return this.innerRequest.IsSecureConnection; } }

        public string this[string key] { get { return this.innerRequest[key]; } }

        public WindowsIdentity LogonUserIdentity { get { return this.innerRequest.LogonUserIdentity; } }

        public NameValueCollection Params { get { return this.innerRequest.Params; } }

        public string Path { get { return this.innerRequest.Path; } }

        public string PathInfo { get { return this.innerRequest.PathInfo; } }

        public string PhysicalApplicationPath { get { return this.innerRequest.PhysicalApplicationPath; } }

        public string PhysicalPath { get { return this.innerRequest.PhysicalPath; } }

        public NameValueCollection QueryString { get { return this.innerRequest.QueryString; } }

        public string RawUrl { get { return this.innerRequest.RawUrl; } }

        public string RequestType { get { return this.innerRequest.RequestType; } set { this.innerRequest.RequestType = value; } }

        public NameValueCollection ServerVariables { get { return this.innerRequest.ServerVariables; } }

        public int TotalBytes { get { return this.innerRequest.TotalBytes; } }

        public Uri Url { get { return this.innerRequest.Url; } }

        public Uri UrlReferrer { get { return this.innerRequest.UrlReferrer; } }

        public string UserAgent { get { return this.innerRequest.UserAgent; } }

        public string UserHostAddress { get { return this.innerRequest.UserHostAddress; } }

        public string UserHostName { get { return this.innerRequest.UserHostName; } }

        public string[] UserLanguages { get { return this.innerRequest.UserLanguages; } }

        #endregion

        #region Methods

        public byte[] BinaryRead(int count)
        {
            return this.innerRequest.BinaryRead(count);
        }

        public int[] MapImageCoordinates(string imageFieldName)
        {
            return this.innerRequest.MapImageCoordinates(imageFieldName);
        }

        public string MapPath(string virtualPath)
        {
            return this.innerRequest.MapPath(virtualPath);
        }

        public string MapPath(string virtualPath, string baseVirtualDir, bool allowCrossAppMapping)
        {
            return this.innerRequest.MapPath(virtualPath, baseVirtualDir, allowCrossAppMapping);
        }

        public void SaveAs(string filename, bool includeHeaders)
        {
            this.innerRequest.SaveAs(filename, includeHeaders);
        }

        public void ValidateInput()
        {
            this.innerRequest.ValidateInput();
        }

        #endregion
    }
}
